package me.ydq;


import me.ydq.convert.ColumnConvert;
import me.ydq.convert.DefaultColumnConvert;
import me.ydq.convert.DefaultTalbeConvert;
import me.ydq.convert.TableConvert;
import me.ydq.core.Table;
import me.ydq.dialect.Dialect;
import me.ydq.dialect.MySQLDialect;
import me.ydq.mapper.DefaultRowMapperProvider;
import me.ydq.mapper.RowMapperProvider;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.util.Optional;

public sealed interface DynamicQuery permits YummyDynamicQuery {

    static DynamicQuery of(NamedParameterJdbcTemplate jdbcTemplate) {
        return of(jdbcTemplate, null, null, null);
    }

    static DynamicQuery of(NamedParameterJdbcTemplate jdbcTemplate, Dialect dialect) {
        return of(jdbcTemplate, dialect, null, null, null);
    }

    static DynamicQuery of(NamedParameterJdbcTemplate jdbcTemplate, TableConvert tableConvert) {
        return of(jdbcTemplate, null, tableConvert, null, null);
    }

    static DynamicQuery of(NamedParameterJdbcTemplate jdbcTemplate, Dialect dialect, TableConvert tableConvert) {
        return of(jdbcTemplate, dialect, tableConvert, null, null);
    }

    static DynamicQuery of(NamedParameterJdbcTemplate jdbcTemplate, TableConvert tableConvert, ColumnConvert columnConvert, RowMapperProvider rowMapperProvider) {
        return of(jdbcTemplate, null, tableConvert, columnConvert, rowMapperProvider);
    }

    static DynamicQuery of(NamedParameterJdbcTemplate jdbcTemplate,
                           Dialect dialect,
                           TableConvert tableConvert,
                           ColumnConvert columnConvert,
                           RowMapperProvider rowMapperProvider) {
        return new YummyDynamicQuery(
                jdbcTemplate,
                Optional.ofNullable(dialect).orElseGet(MySQLDialect::new),
                Optional.ofNullable(tableConvert).orElseGet(DefaultTalbeConvert::new),
                Optional.ofNullable(columnConvert).orElseGet(DefaultColumnConvert::new),
                Optional.ofNullable(rowMapperProvider).orElseGet(DefaultRowMapperProvider::new)
        );
    }

    <T> Table<T> table(Class<T> cls);

    /**
     * 指定表名，用于部分实体和其他实体定义的表名转换不一致的特殊处理
     */
    <T> Table<T> table(Class<T> cls, String tableName);

    /**
     * 指定表名转换器，适用于部分实体和其他实体定义的表名转换不一致的特殊处理
     */
    <T> Table<T> table(Class<T> cls, TableConvert tableConvert);

    /**
     * 如果自定义 列名转换器，大概率 读取出来的对象也需要定制 RowMapper，适用于部分实体和其他实体定义的不一致的特殊处理
     */
    <T> Table<T> table(Class<T> cls, String tableName, ColumnConvert columnConvert, RowMapper<T> rowMapper);

    /**
     * 如果自定义 列名转换器，大概率 读取出来的对象也需要定制 RowMapper，适用于部分实体和其他实体定义的不一致的特殊处理
     */
    <T> Table<T> table(Class<T> cls, TableConvert tableConvert, ColumnConvert columnConvert, RowMapper<T> rowMapper);
}
